package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

/**
 * Spring Boot 主启动类
 * 
 * 🔍 @SpringBootApplication 注解解析：
 * 这个注解实际上是三个注解的组合（元注解）：
 * 
 * 1️⃣ @Configuration：
 *    - 作用：标识这是一个配置类，等价于传统的XML配置
 *    - 功能：可以在这里定义@Bean方法
 *    - 原理：Spring会扫描并处理@Configuration类中的Bean定义
 * 
 * 2️⃣ @EnableAutoConfiguration：
 *    - 作用：启用Spring Boot的自动配置机制  
 *    - 功能：根据classpath中的jar包自动配置Bean
 *    - 原理：扫描META-INF/spring.factories文件中的自动配置类
 * 
 * 3️⃣ @ComponentScan：
 *    - 作用：自动扫描组件（@Component, @Service, @Repository, @Controller等）
 *    - 功能：从当前包开始递归扫描子包
 *    - 原理：将扫描到的组件注册为Spring Bean
 * 
 * 📚 等价写法：
 * @Configuration
 * @EnableAutoConfiguration  
 * @ComponentScan
 * public class Application { ... }
 */
@SpringBootApplication
public class Application {
    
    /**
     * 📚 演示@Configuration功能：手动定义Bean
     * 
     * 这个方法演示了@SpringBootApplication中包含的@Configuration功能
     * 相当于在传统Spring XML中定义 <bean id="appInfo" class="AppInfo"/>
     */
    @Bean
    public AppInfo appInfo() {
        System.out.println("🔧 创建AppInfo Bean (来自@Configuration功能)");
        return new AppInfo(
            "Spring Boot Demo", 
            "1.0.0", 
            "学习Spring Boot核心概念的演示项目"
        );
    }
    
    /**
     * 应用信息类 - 演示用
     */
    public static class AppInfo {
        private final String name;
        private final String version; 
        private final String description;
        
        public AppInfo(String name, String version, String description) {
            this.name = name;
            this.version = version;
            this.description = description;
        }
        
        @Override
        public String toString() {
            return String.format("📱 应用信息: %s v%s - %s", name, version, description);
        }
        
        // Getters
        public String getName() { return name; }
        public String getVersion() { return version; }
        public String getDescription() { return description; }
    }

    /**
     * 应用程序入口点
     * 
     * 🚀 SpringApplication.run() 启动过程：
     * 1. 创建SpringApplication实例
     * 2. 推断应用类型（Web应用 vs 非Web应用）
     * 3. 加载并实例化ApplicationContextInitializer
     * 4. 加载并实例化ApplicationListener
     * 5. 推断主配置类（这里是Application）
     * 6. 启动应用上下文
     * 7. 执行自动配置
     * 8. 扫描并注册组件
     * 9. 启动嵌入式Web服务器（如Tomcat）
     */
    public static void main(String[] args) {
        System.out.println("🚀 === Spring Boot 应用启动开始 ===");
        System.out.println("📦 主配置类: " + Application.class.getName());
        System.out.println("🔍 扫描包路径: com.example");
        System.out.println("⚙️  自动配置: 已启用");
        
        // 启动Spring Boot应用
        SpringApplication.run(Application.class, args);
        
        System.out.println("✅ === Spring Boot 应用启动完成 ===");
    }
}
